﻿//-----------------------------------------------------------------------
// <Copyright>
// * Copyright (C) 2022 RuYiAdmin All Rights Reserved
// </Copyright>
//-----------------------------------------------------------------------

using AutoMapper;
using Microsoft.Extensions.Logging;
using Quartz;
using RuYiAdmin.Net.DataModel.DataTransformationModel.Sys;
using RuYiAdmin.Net.DataModel.EntityDataModel.Sys;
using RuYiAdmin.Net.SystemService.BusinessService.Interface.Framework;
using RuYiAdmin.Net.SystemService.BusinessService.Interface.Sys;
using RuYiAdmin.Net.UniversalFoundation.Configurations;
using RuYiAdmin.Net.UniversalFoundation.Enums.Business;
using RuYiAdmin.Net.UniversalFoundation.GeneralFoundationClass;
using RuYiAdmin.Net.UniversalFoundation.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RuYiAdmin.Net.WebApi.RuYiAdminCode.RuYiAdminQuartzJob
{
    [DisallowConcurrentExecution]
    public class RuYiAdminFrameworkJob : IJob
    {
        private readonly ILogger<RuYiAdminFrameworkJob> Logger;

        /// <summary>
        /// Redis接口实例
        /// </summary>
        private readonly IRedisService RedisService;

        /// <summary>
        /// AutoMapper实例
        /// </summary>
        private readonly IMapper AutoMapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Logger">日志对象</param>
        /// <param name="RedisService">Redis接口实例</param>
        ///  <param name="AutoMapper">AutoMapper实例</param>
        public RuYiAdminFrameworkJob(ILogger<RuYiAdminFrameworkJob> Logger,
                                     IRedisService RedisService,
                                     IMapper AutoMapper)
        {
            this.Logger = Logger;
            this.RedisService = RedisService;
            this.AutoMapper = AutoMapper;
        }

        /// <summary>
        /// 执行框架作业
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task Execute(IJobExecutionContext context)
        {
            this.CleanTempPath();//清理临时文件
            this.SyncUserToOpenIM();//向OpenIM同步用户
            this.Logger.LogInformation("RuYiAdmin Framework Job:Task completed!");
            return Task.CompletedTask;
        }

        #region 清理临时文件

        /// <summary>
        /// 清理临时文件
        /// </summary>
        private void CleanTempPath()
        {
            if (DateTime.Now.Hour.Equals(4) && DateTime.Now.Minute.Equals(0))
            {
                string day = DateTime.Now.ToString("yyyy-MM-dd");
                String key = "RuYiAdmin-Framework-Job-" + day;
                if (!this.RedisService.Exists(key))
                {
                    RuYiGlobalConfig.DirectoryConfig.CleanTempPath();//凌晨4点清理临时文件、释放服务器存储空间
                    this.RedisService.Set(key, true, 60 * 60);//设置Redis缓存，过期时间为1小时
                    this.Logger.LogInformation($"RuYiAdmin Framework Job: {day}:temporary files cleaned successfully!");
                }
            }
        }

        #endregion

        #region 向OpenIM同步用户

        /// <summary>
        /// 向OpenIM同步用户
        /// </summary>
        private void SyncUserToOpenIM()
        {
            if (RuYiGlobalConfig.OpenIMConfig.IsOpenIMEnabled)
            {
                string userKey = RuYiGlobalConfig.SystemCacheConfig.UserCacheName;
                var allUsers = this.RedisService.Get<List<SysUserDTO>>(userKey);
                var users = allUsers.Where(t => t.IsDel == (int)DeletionType.Undeleted
                                      && t.IsEnabled == (int)UserStatus.Enabled
                                      && t.Extend2 == null).ToList();//启用且未同步到OpenIM的用户
                if (users.Count > 0)
                {
                    List<OpenIMUserInfo> userInfos = new List<OpenIMUserInfo>();
                    foreach (var item in users)
                    {
                        if (!string.IsNullOrEmpty(item.MobilePhone))
                        {
                            var userInfo = new OpenIMUserInfo();

                            userInfo.Nickname = item.DisplayName;

                            switch (item.Sex)
                            {
                                case 0:
                                    userInfo.Gender = 1; // 男
                                    break;
                                case 1:
                                    userInfo.Gender = 2;// 女
                                    break;
                                case 2:
                                    userInfo.Gender = 0;//未知性别
                                    break;
                            }

                            userInfo.PhoneNumber = item.MobilePhone;

                            if (!string.IsNullOrEmpty(item.Extend1))
                            {
                                DateTime birthDate;
                                if (DateTime.TryParse(item.Extend1, out birthDate))
                                {
                                    userInfo.Birth = (long)(birthDate.ToUniversalTime() -
                                        new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
                                }
                                else
                                {
                                    userInfo.Birth = 0; // 如果解析失败，设置为0
                                }
                            }
                            else
                            {
                                userInfo.Birth = 0; // 如果没有出生日期，设置为0
                            }

                            var aesKey = RuYiGlobalConfig.SystemConfig.AesKey;
                            string password = RuYiAesUtil.Decrypt(item.Password, aesKey).Replace(item.Salt.ToString(), "");//AES解密
                            userInfo.Password = RuYiMd5Util.Encrypt(password);//MD5单向加密

                            userInfos.Add(userInfo);

                            item.Extend2 = "1"; // 标记为已同步
                            item.Modifier = Guid.Empty;//清空修改人，为空默认为管理员或者系统修改
                            item.ModifyTime = DateTime.Now;//更新时间
                            item.VersionId = Guid.NewGuid();//更新版本号
                        }
                    }

                    RuYiOpenIMUtil.SyncUserInfo(userInfos).GetAwaiter().GetResult();

                    users = users.Where(t => t.Extend2 == "1").ToList();
                    if (users.Count > 0)
                    {
                        foreach (var item in users)
                        {
                            var user = AutoMapper.Map<SysUser>(item);
                            RuYiAdminDbSession.RuYiDbContext.Updateable<SysUser>(user).ExecuteCommand();//更新用户信息，标记为已同步

                            //数据一致性维护                                                                            
                            var old = allUsers.Where(t => t.Id == item.Id).FirstOrDefault();
                            allUsers.Remove(old);//删除就数据
                            allUsers.Add(item);//添加新数据
                        }
                        this.RedisService.Set(userKey, allUsers, -1);//更新用户缓存
                        this.Logger.LogInformation("RuYiAdmin Framework Job: OpenIM user info synchronized successfully!");
                    }
                }
            }
        }

        #endregion
    }
}